package com.qf.smartplatform.websocket;

import com.qf.smartplatform.events.CommandEvent;
import com.qf.smartplatform.pojo.DeviceOnOffLineEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * projectName:day12_27_Test
 * author:guoLei
 * time:2022/1/10 14:05
 * description:
 */
public class MyBaseCommandHandler extends TextWebSocketHandler {

    private ApplicationContext applicationContext;

    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    private static Map<String, WebSocketSession> socketSessionMap = new HashMap<>();

    private static Map<String, Long> longHashMap = new HashMap<>();

    public static Map<String, WebSocketSession> getAllClients() {
        return socketSessionMap;
    }

    public static Map<String, Long> getAllClientLastHeartbeat() {
        return longHashMap;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String s = session.getUri().toString();
        String substring = s.substring(s.lastIndexOf("/") + 1);
        WebSocketSession webSocketSession = socketSessionMap.get(s);
        if (webSocketSession != null) {
            webSocketSession.close();
        }
        session.getAttributes().put("id", s);
        socketSessionMap.put(s, session);
        System.err.println("设备" + s + "连接成功");
        longHashMap.put(s, System.currentTimeMillis());
        applicationContext.publishEvent(new DeviceOnOffLineEvent(s, new Date(), session.getRemoteAddress().getHostString(), 1L));
        super.afterConnectionEstablished(session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
        Object id = session.getAttributes().get("id");
        String payload = message.getPayload();
        System.err.println("收到设备" + id + "发来的数据：==>" + payload);
        longHashMap.put((String) id, System.currentTimeMillis());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        applicationContext.publishEvent(new DeviceOnOffLineEvent((String) session.getAttributes().get("id"), new Date(), null, 2L));
    }

    public static void sendControl(CommandEvent event) {
        Object command = event.getCommand();
        String uid = event.getUid();
        WebSocketSession session = socketSessionMap.get(uid);
        if (session != null && session.isOpen()) {
            try {
                session.sendMessage(new TextMessage(command.toString()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void checkStatus() {
        CompletableFuture.runAsync(() -> {
            HashMap<String, Long> hashMap = new HashMap<>();
            hashMap.putAll(longHashMap);
            hashMap.forEach((id, time) -> {
                long currentTimeMillis = System.currentTimeMillis();
                if (currentTimeMillis - time >= 60000) {
                    System.err.println("设备:" + id + "已经离线了");
                    WebSocketSession socketSession = socketSessionMap.get(id);
                    if (socketSession != null && socketSession.isOpen()) {
                        try {
                            socketSession.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    socketSessionMap.remove(id);
                    longHashMap.remove(id);
                }
            });
            hashMap.clear();
        });
    }

}
